函数定义

  在程序里调用的每个函数都必须在某个地方定义(仅仅一次)。一个函数定义也就是一个给出了函数体的函数声明。例如,

    extern void swap(int*, int*);    // 声明
    void swap(int*p, int* q)         // 定义
    {
        int t = *p;
        *p = *q;
        *q = t;
    }

一个函数的定义和对它的所有声明必须都描述了同样的类型。不过,这里并不把参数名字作为类型的一部分,因此参数名不必保持一致。

  在函数的定义里,可以存在不使用的参数,这也是常看到的情况:

    void search(table* t, const char* key, const char*)
    {
        // 第三个参数没有使用
    }

如上所示,根本不使用的参数可以采用不予命名的方式明示。典型情况是,出现未命名参数的原因是做过代码的简化,或者是计划在将来做功能扩充。对于这两种情况,虽然不使用但还是让参数留在那里,就能保证那些调用函数的地方不会受到修改的影响。

  函数可以定义为inline(在线的)。例如,

    inline int fac(int n)
    {
        return (n < 2) ? 1 : n * fac(n - 1);
    }

inline描述符是给编译器的一个提示,要求它试着把所有对fac()的调用在线化,而不是仅仅一次放好函数的代码,而后通过正常的函数调用机制调用这段代码。一个聪明的编译器也可能直接对调用fac(6)产生出常量720。互相递归的在线函数、自递归的或者并不依赖于输入的在线函数等的存在,使得保证所有inline函数的调用都能在线化是根本不可能的。对编译器的聪明程度并没有做任何明确规定,所以对于上例,某个编译器可能产生720,另一个可能是6 * fac(5),再有一个产生出完全没有在线化的fac(6)。

  要在不存在特别聪明的编译器和连接机制的情况下使在线化有可能进行,在线函数的定义---而不仅仅是它的声明---就必须在作用域里(9.2节)。inline描述符并不影响函数的语义。特别地,每个在线函数仍然会有自己的独立地址,在线函数里的那些static变量(7.1.2节)也将有自己的地址。

🔚